import { useEffect, useRef } from 'preact/hooks'
import ForceGraph2D from 'force-graph'
import { gsap } from 'gsap'

export default function KnowledgeGraph({ graphData, setGraphData, recommendations }) {
  const containerRef = useRef(null)
  const graphRef = useRef(null)

  useEffect(() => {
    if (!containerRef.current) return

    // 初始化2D力导向图 (Obsidian风格)
    const Graph = ForceGraph2D()(containerRef.current)
      .graphData(graphData)
      .nodeLabel('name')
      .nodeVal(node => node.val || 8)
      .nodeCanvasObject((node, ctx, globalScale) => {
        drawNode(node, ctx, globalScale)
      })
      .nodePointerAreaPaint((node, color, ctx) => {
        ctx.fillStyle = color
        const size = 5
        ctx.beginPath()
        ctx.arc(node.x, node.y, size * 1.5, 0, 2 * Math.PI, false)
        ctx.fill()
      })
      .linkColor(link => link.color || 'rgba(150, 150, 150, 0.4)')  // 默认灰色
      .linkWidth(link => link.highlighted ? 3 : 1.5)
      .linkDirectionalParticles(link => link.particles || 0)
      .linkDirectionalParticleSpeed(0.005)
      .linkDirectionalParticleWidth(3)
      .linkDirectionalParticleColor(link => link.particleColor || '#00D9FF')
      .backgroundColor('#1a1a2e')
      .enableNodeDrag(true)
      .enableZoomInteraction(true)
      .enablePanInteraction(true)
      .d3AlphaDecay(0.02)
      .d3VelocityDecay(0.3)
      .cooldownTime(3000)
      .onNodeHover(node => {
        containerRef.current.style.cursor = node ? 'pointer' : 'default'
      })
      .onNodeClick(async (node) => {
        if (node) {
          await handleNodeClick(node, Graph)
        }
      })

    // 自动调整画布大小
    const resizeObserver = new ResizeObserver(() => {
      if (graphRef.current) {
        const rect = containerRef.current.getBoundingClientRect()
        Graph.width(rect.width).height(rect.height)
      }
    })
    resizeObserver.observe(containerRef.current)

    graphRef.current = Graph

    return () => {
      resizeObserver.disconnect()
      if (graphRef.current) {
        graphRef.current._destructor()
      }
    }
  }, [])

  // 更新图数据
  useEffect(() => {
    if (graphRef.current && graphData) {
      graphRef.current.graphData(graphData)
    }
  }, [graphData])

  // 高亮推荐路径 - 已禁用颜色动画
  // useEffect(() => {
  //   if (recommendations.length > 0 && graphRef.current) {
  //     animateRecommendationPaths(recommendations, graphRef.current, graphData, setGraphData)
  //   }
  // }, [recommendations])

  return (
    <div
      ref={containerRef}
      class="w-full h-full"
      style={{ position: 'absolute', top: 0, left: 0 }}
    />
  )
}

// 绘制节点 (Obsidian风格)
function drawNode(node, ctx, globalScale) {
  const size = 5  // 节点大小
  const fontSize = 11 / globalScale
  const labelOffsetY = 12  // 标签向下偏移距离

  // 根据节点类型确定颜色
  let nodeColor
  if (node.highlighted) {
    nodeColor = '#00D9FF'
  } else if (node.type === 'topic') {
    nodeColor = node.color || '#4ECDC4'
  } else if (node.type === 'user') {
    nodeColor = '#FF6B6B'
  } else {
    nodeColor = '#00D9FF'
  }

  // 绘制节点圆圈
  ctx.beginPath()
  ctx.arc(node.x, node.y, size, 0, 2 * Math.PI, false)

  // 填充
  ctx.fillStyle = nodeColor
  ctx.fill()

  // 描边
  ctx.strokeStyle = node.highlighted ? '#ffffff' : nodeColor
  ctx.lineWidth = node.highlighted ? 2.5 : 1.5
  ctx.stroke()

  // 发光效果 - 高亮或新建的节点
  if (node.highlighted || node.new) {
    ctx.shadowBlur = 25
    ctx.shadowColor = nodeColor

    // 绘制外圈光晕
    ctx.globalAlpha = 0.6
    ctx.beginPath()
    ctx.arc(node.x, node.y, size * 2, 0, 2 * Math.PI, false)
    ctx.strokeStyle = nodeColor
    ctx.lineWidth = 3
    ctx.stroke()
    ctx.globalAlpha = 1.0

    // 内圈高亮
    ctx.beginPath()
    ctx.arc(node.x, node.y, size, 0, 2 * Math.PI, false)
    ctx.stroke()
    ctx.shadowBlur = 0
  }

  // 绘制标签 - 只在缩放级别合适时显示
  if (globalScale > 0.8) {
    const label = node.name || node.id

    ctx.font = `${fontSize}px -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`
    ctx.textAlign = 'center'
    ctx.textBaseline = 'top'

    // 添加半透明背景让文字更清晰
    const textWidth = ctx.measureText(label).width
    const padding = 4
    const bgHeight = fontSize + padding

    ctx.fillStyle = 'rgba(26, 26, 46, 0.85)'
    ctx.fillRect(
      node.x - textWidth / 2 - padding / 2,
      node.y + labelOffsetY - padding / 2,
      textWidth + padding,
      bgHeight
    )

    // 绘制文字
    ctx.fillStyle = '#ffffff'
    ctx.fillText(label, node.x, node.y + labelOffsetY)
  }
}

// 聚焦节点
function focusOnNode(node, Graph) {
  // 平滑缩放到节点
  Graph.centerAt(node.x, node.y, 1000)
  Graph.zoom(2, 1000)
}

// 处理节点点击 - 显示向量信息
async function handleNodeClick(node, Graph) {
  focusOnNode(node, Graph)

  // 获取节点的embedding向量
  try {
    const response = await fetch('/api/node-embedding', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        label: node.name || node.label
      })
    })

    const data = await response.json()

    if (data.success) {
      // 显示向量信息
      const message = `节点: ${data.label}\n维度: ${data.dimension}\n向量范数: ${data.norm.toFixed(4)}\n前10维: [${data.embedding.map(v => v.toFixed(4)).join(', ')}...]`

      // 创建一个浮动提示框
      showNodeInfo(node, message)
    }
  } catch (error) {
    console.error('获取节点向量失败:', error)
  }
}

// 显示节点信息
function showNodeInfo(node, message) {
  // 移除之前的提示框
  const existing = document.getElementById('node-info-tooltip')
  if (existing) {
    existing.remove()
  }

  // 创建新的提示框
  const tooltip = document.createElement('div')
  tooltip.id = 'node-info-tooltip'
  tooltip.style.cssText = `
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: rgba(26, 26, 46, 0.95);
    color: white;
    padding: 20px;
    border-radius: 8px;
    border: 1px solid #00D9FF;
    font-family: monospace;
    font-size: 12px;
    white-space: pre;
    z-index: 1000;
    max-width: 80%;
    box-shadow: 0 4px 20px rgba(0, 217, 255, 0.3);
  `
  tooltip.textContent = message

  // 点击关闭
  tooltip.addEventListener('click', () => {
    tooltip.remove()
  })

  document.body.appendChild(tooltip)

  // 3秒后自动关闭
  setTimeout(() => {
    if (tooltip.parentNode) {
      tooltip.remove()
    }
  }, 5000)
}

// 动画展示推荐路径
function animateRecommendationPaths(recommendations, Graph, graphData, setGraphData) {
  recommendations.forEach((rec, index) => {
    setTimeout(() => {
      const pathIds = rec.path_ids || []
      const isFirst = rec.is_first || index === 0
      const recommendationColor = rec.color || '#00D9FF'

      // 如果是第一条推荐，先重置所有连线为灰色
      if (isFirst && index === 0) {
        setGraphData((prev) => ({
          ...prev,
          links: prev.links.map(l => ({
            ...l,
            color: 'rgba(150, 150, 150, 0.4)',
            highlighted: false,
            particles: 0
          })),
          nodes: prev.nodes.map(n => ({
            ...n,
            highlighted: false
          }))
        }))
      }

      // 高亮路径上的节点
      pathIds.forEach((nodeId, i) => {
        setTimeout(() => {
          setGraphData((prev) => ({
            ...prev,
            nodes: prev.nodes.map(n => {
              if (n.id === nodeId) {
                return { ...n, highlighted: true }
              }
              return n
            })
          }))

          // 节点脉冲动画
          const node = graphData.nodes.find(n => n.id === nodeId)
          if (node) {
            const originalSize = node.val || 8
            gsap.to(node, {
              val: originalSize * 1.8,
              duration: 0.3,
              yoyo: true,
              repeat: 1,
              ease: "power2.inOut",
              onUpdate: () => {
                Graph.refresh()
              }
            })
          }
        }, i * 300)
      })

      // 高亮路径上的连线
      for (let i = 0; i < pathIds.length - 1; i++) {
        setTimeout(() => {
          setGraphData((prev) => ({
            ...prev,
            links: prev.links.map(l => {
              const sourceId = l.source.id || l.source
              const targetId = l.target.id || l.target

              if (
                (sourceId === pathIds[i] && targetId === pathIds[i + 1]) ||
                (sourceId === pathIds[i + 1] && targetId === pathIds[i])
              ) {
                return {
                  ...l,
                  color: recommendationColor,
                  highlighted: true,
                  particles: 3,
                  particleColor: recommendationColor
                }
              }
              return l
            })
          }))
        }, i * 300)
      }

      // 不自动移动镜头，让用户自由观察连线颜色变化
    }, index * 2000)
  })
}
